package net.boot.smpp.task;

import lombok.extern.slf4j.Slf4j;
import org.jsmpp.PDUStringException;
import org.jsmpp.SMPPConstant;
import org.jsmpp.bean.*;
import org.jsmpp.session.BindRequest;
import org.jsmpp.session.SMPPServerSession;
import org.jsmpp.util.DeliveryReceiptState;
import org.jsmpp.util.MessageId;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeoutException;

/**
 * @author qiusu
 * @since  2025/08/18
 */
@Slf4j
@Component
public class SmppPoolTask {

    @Value("${jsmpp.systemId}")
    private String systemId;

    @Value("${jsmpp.password}")
    private String password;

    @Async("waitBindExecService")
    public void waitBindTask(SMPPServerSession serverSession, long timeout) {
        try {
            log.info("Waiting {} ms for bind for session {} ", timeout, serverSession.getSessionId());
            BindRequest bindRequest = serverSession.waitForBind(timeout);
            log.info("Accepting bind for session {}", serverSession.getSessionId());

            if (systemId.equals(bindRequest.getSystemId()) && password.equals(bindRequest.getPassword())) {
                try {
                    serverSession.setInterfaceVersion(InterfaceVersion.IF_50.min(bindRequest.getInterfaceVersion()));
                    bindRequest.accept("sys", InterfaceVersion.IF_50);
                } catch (PDUStringException e) {
                    log.error("Invalid system id", e);
                    bindRequest.reject(SMPPConstant.STAT_ESME_RINVSYSID);
                }
            }else {
                log.info("密码错误Rejecting bind request");
                bindRequest.reject(SMPPConstant.STAT_ESME_RINVPASWD);
            }

        } catch (IllegalStateException e) {
            log.error("System error", e);
        } catch (TimeoutException e) {
            log.warn("Timeout: {}", e.getMessage());
        } catch (IOException e) {
            log.error("Failed accepting bind request for session {}", serverSession.getSessionId());
        }
    }

    @Async("deliveryExecService")
    public void deliveryReceiptTask(SMPPServerSession session, SubmitSm submitSm, MessageId messageId) {
        String stringValue = Integer.valueOf(messageId.getValue(), 16).toString();
        try {

            // 在方法内部实现延迟
            Thread.sleep(1000);  // 延迟1秒

            DeliveryReceipt delRec = new DeliveryReceipt(stringValue, 1, 1, new Date(), new Date(), DeliveryReceiptState.DELIVRD,  null, new String(submitSm.getShortMessage()));
            session.deliverShortMessage(
                    "mc",
                    TypeOfNumber.valueOf(submitSm.getDestAddrTon()),
                    NumberingPlanIndicator.valueOf(submitSm.getDestAddrNpi()),
                    submitSm.getDestAddress(),
                    TypeOfNumber.valueOf(submitSm.getSourceAddrTon()),
                    NumberingPlanIndicator.valueOf(submitSm.getSourceAddrNpi()),
                    submitSm.getSourceAddr(),
                    new ESMClass(MessageMode.DEFAULT, MessageType.SMSC_DEL_RECEIPT, GSMSpecificFeature.DEFAULT),
                    (byte)0,
                    (byte)0,
                    new RegisteredDelivery(0),
                    DataCodings.ZERO,
                    delRec.toString().getBytes());
            log.debug("Sending delivery receipt for message id {}: {}", messageId, stringValue);
        } catch (Exception e) {
            log.error("Failed sending delivery_receipt for message id " + messageId + ":" + stringValue, e);
        }
    }
}
